/**
 *	@file	n_planter.c
 *	@brief	木の実プランターシステム(常駐)
 *	@author	Miyuki Iwasawa
 *	@date	08.08.04
 */

#include "common.h"
#include "system/procsys.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/snd_tool.h"
#include "system/fontproc.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/buflen.h"
#include "system/window.h"
#include "system/brightness.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/palanm.h"
#include "system/wipe.h"
#include "system/window.h"
#include "system/font_arc.h"
#include "system/winframe.naix"
#include "gflib/touchpanel.h"
#include "msgdata/msg.naix"

#include "savedata/config.h"
#include "application/bag.h"
#include "application/nut_planter.h"
#include "np_sys.h"
#include "np_tool.h"
#include "np_app.h"

#include "system/pm_overlay.h"

#ifdef DEBUG_ONLY_FOR_iwasawa
 #undef IWASAWA_PRINT
 #define IWASAWA_PRINT(...) ((void) 0)
#endif

FS_EXTERN_OVERLAY(nut_planter);

//=========================================================
//データ型定義
//=========================================================
//システムシーケンス定義
enum{
 SSEQ_APPCALL,
 SSEQ_APPWAIT,
 SSEQ_BAGCALL,
 SSEQ_BAGWAIT,
 SSEQ_EXIT,
};

//=========================================================
//プロトタイプ
//=========================================================
static BOOL NPlanterSysProcCall(PROC** proc);
static void sys_InitData(NP_SYSWORK* wk);
static void sys_EndData(NP_SYSWORK* wk);


static int seq_AppCall(NP_SYSWORK* wk);
static int seq_AppWait(NP_SYSWORK* wk);
static int seq_BagCall(NP_SYSWORK* wk);
static int seq_BagWait(NP_SYSWORK* wk);

//=========================================================
//コードエリア
//=========================================================
/**
 *	@brief	サブプロセス呼び出し処理
 */
static BOOL NPlanterSysProcCall(PROC** proc)
{
	if(*proc){
		if(ProcMain(*proc)){
			PROC_Delete(*proc);
			*proc = NULL;
			return TRUE;
		}
	}
	return FALSE;
}

//=========================================================
//プロセス定義
//=========================================================
/**
 *	@brief	木の実プランターモジュール呼び出し
 */
PROC_RESULT NPlanterSysProc_Init(PROC* proc,int* seq)
{
	NP_SYSWORK* wk = NULL;

	Overlay_Load( FS_OVERLAY_ID( nut_planter ), OVERLAY_LOAD_NOT_SYNCHRONIZE );

	NPTool_ViewClear();

	//ヒープ作成
	HeapStatePush();
	sys_CreateHeap(HEAPID_BASE_APP,HEAPID_NPLANTER_SYS,0x20000);

	wk = PROC_AllocWork(proc,sizeof(NP_SYSWORK),HEAPID_NPLANTER_SYS);
	MI_CpuClear8(wk,sizeof(NP_SYSWORK));

	wk->heapID = HEAPID_NPLANTER_SYS;
	wk->param = (NPLANTER_PARAM*)PROC_GetParentWork(proc);

	//引継ぎデータ初期化
	sys_InitData(wk);

	return PROC_RES_FINISH;
}

/**
 *	@brief	木の実プランターモジュールメイン
 */
PROC_RESULT NPlanterSysProc_Main(PROC* proc,int* seq)
{
	NP_SYSWORK* wk = (NP_SYSWORK*)PROC_GetWork(proc);

	switch(*seq){
	case SSEQ_APPCALL:
		*seq = seq_AppCall(wk);
		break;
	case SSEQ_APPWAIT:
		*seq = seq_AppWait(wk);
		break;
	case SSEQ_BAGCALL:
		*seq = seq_BagCall(wk);
		break;
	case SSEQ_BAGWAIT:
		*seq = seq_BagWait(wk);
		break;
	case SSEQ_EXIT:
		return PROC_RES_FINISH;
	}
	return PROC_RES_CONTINUE;
}

/**
 *	@brief	木の実プランターモジュール終了
 */
PROC_RESULT NPlanterSysProc_End(PROC* proc,int* seq)
{
	NP_SYSWORK* wk = (NP_SYSWORK*)PROC_GetWork(proc);

	NPTool_ViewClear();

	//引継ぎデータ書き戻し
	sys_EndData(wk);

	//ワーク解放
	PROC_FreeWork(proc);

	HeapStatePop();
	HeapStateCheck(HEAPID_NPLANTER_SYS);

	sys_DeleteHeap(HEAPID_NPLANTER_SYS);

	Overlay_UnloadID( FS_OVERLAY_ID( nut_planter ) );

	return PROC_RES_FINISH;
}

///////////////////////////////////////////////////////////////////////////////
//サブ

/**
 *	@brief	引継ぎデータ初期化
 */
static void sys_InitData(NP_SYSWORK* wk)
{
	wk->kinomi_cursor = MyItem_BagCursorAlloc(wk->heapID);
	wk->koyashi_cursor = MyItem_BagCursorAlloc(wk->heapID);
}

/**
 *	@brief	引継ぎデータ終了処理
 */
static void sys_EndData(NP_SYSWORK* wk)
{
	sys_FreeMemoryEz(wk->koyashi_cursor);
	sys_FreeMemoryEz(wk->kinomi_cursor);
}

/**
 *	@brief	プランターアプリコール
 */
static int seq_AppCall(NP_SYSWORK* wk)
{
	// オーバーレイID宣言
//	FS_EXTERN_OVERLAY(nut_planter);

	static const PROC_DATA NPlanterProcData = {
		NPlanterProc_Init,
		NPlanterProc_Main,
		NPlanterProc_End,
//		FS_OVERLAY_ID(nut_planter),
		NO_OVERLAY_ID,
	};

	wk->proc = PROC_Create(&NPlanterProcData,wk,wk->heapID);

	return SSEQ_APPWAIT;
}

/**
 *	@brief	プランターアプリ待ち
 */
static int seq_AppWait(NP_SYSWORK* wk)
{
	if(!NPlanterSysProcCall(&wk->proc)){
		return SSEQ_APPWAIT;
	}
	if(wk->mode == SYSMODE_COMPOST || wk->mode == SYSMODE_SEED){
		return SSEQ_BAGCALL;
	}
	return SSEQ_EXIT;
}

/**
 *	@brief	バッグアプリコール
 */
static int seq_BagCall(NP_SYSWORK* wk)
{
	static const u8 * baglist;
	static const u8 kinomi_bag[] = {BAG_POKE_NUTS, 0xff};
	static const u8 dougu_bag[] = {BAG_POKE_NORMAL, 0xff};
	MYITEM * myitem = SaveData_GetMyItem(wk->param->save);

	switch (wk->mode) {
	case SYSMODE_COMPOST:
		baglist = dougu_bag;
		wk->app_wk = MyItem_MakeBagData(myitem, baglist, wk->heapID );
		BAG_SysDataSet( wk->app_wk, wk->param->save, BAG_MODE_N_PLANTER,
					wk->koyashi_cursor, wk->param->kt_status );
		break;
	case SYSMODE_SEED:
		baglist = kinomi_bag;
		wk->app_wk = MyItem_MakeBagData(myitem, baglist, wk->heapID );
		BAG_SysDataSet( wk->app_wk, wk->param->save, BAG_MODE_N_PLANTER,
					wk->kinomi_cursor, wk->param->kt_status );
		break;
	default:
		GF_ASSERT(0);
	}

	{
		// オーバーレイID宣言
		FS_EXTERN_OVERLAY(fld_bag);

		static const PROC_DATA BagProcData = {
			BagProc_Init,
			BagProc_Main,
			BagProc_End,
			FS_OVERLAY_ID(fld_bag)
		};
		wk->proc = PROC_Create(&BagProcData,wk->app_wk,wk->heapID);
	}
	return SSEQ_BAGWAIT;
}

/**
 *	@brief	バッグアプリ終了待ち
 */
static int seq_BagWait(NP_SYSWORK* wk)
{
	u8 ret_mode;

	if(!NPlanterSysProcCall(&wk->proc)){
		return SSEQ_BAGWAIT;
	}

	ret_mode = BagSysReturnModeGet( wk->app_wk );

	if(ret_mode == BAG_RET_POKEITEMSET){
		wk->ret_item = BagSysReturnItemGet( wk->app_wk );
	}else{
		wk->ret_item = 0xFFFF;
	}
	IWASAWA_PRINT("選んだアイテム %d\n",wk->ret_item);
	sys_FreeMemoryEz(wk->app_wk);
	wk->app_wk = NULL;

	return SSEQ_APPCALL;
}